package com.ilxqx.framework.system.controller;

import com.ilxqx.framework.security.constant.SecurityConstants;
import com.ilxqx.framework.security.util.AuthUtils;
import com.ilxqx.framework.system.controller.base.AbstractFrameworkController;
import com.ilxqx.framework.system.entity.SysRole;
import com.ilxqx.framework.system.entity.SysUser;
import com.ilxqx.framework.system.exception.UpdateDeniedException;
import com.ilxqx.framework.system.form.search.SysUserSearchForm;
import com.ilxqx.framework.system.form.update.SysUserUpdateForm;
import com.ilxqx.framework.system.service.SysRoleService;
import com.ilxqx.framework.system.service.SysUserService;
import com.ilxqx.framework.util.ResultUtils;
import com.ilxqx.framework.vo.ResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户控制器
 * @author venus
 */
@Api("用户控制器")
@RestController
@RequestMapping("/auth/sys-user")
@Slf4j
public class SysUserController extends AbstractFrameworkController<SysUser, Long, SysUserSearchForm, SysUserUpdateForm> {

	private final SysUserService sysUserService;
	private final PasswordEncoder passwordEncoder;
	private final SysRoleService sysRoleService;

	@Autowired
	public SysUserController(SysUserService sysUserService, PasswordEncoder passwordEncoder, SysRoleService sysRoleService) {
		super(sysUserService);
		this.sysUserService = sysUserService;
		this.passwordEncoder = passwordEncoder;
		this.sysRoleService = sysRoleService;
	}

	/**
	 * 在实体创建之前处理实体属性数据
	 *
	 * @param entity 实体对象
	 * @param form   表单对象
	 */
	@Override
	public void beforeAdd(SysUser entity, SysUserUpdateForm form) {
		// 设置加密
		entity.setPassword(this.passwordEncoder.encode(form.getPassword()));
	}

	/**
	 * 在实体修改之前处理实体属性数据
	 *
	 * @param entity 实体对象
	 * @param form   表单对象
	 */
	@Override
	public void beforeModify(SysUser entity, SysUserUpdateForm form) {
		// 如果是超级管理员用户，则只能由超级管理员来修改
		if (Objects.equals(entity.getUserId(), SecurityConstants.SUPER_ADMIN_USER_ID) &&
			!Objects.equals(AuthUtils.getLoggedUserId(), SecurityConstants.SUPER_ADMIN_USER_ID)) {
			throw new UpdateDeniedException("您没有权限修改超级管理员的信息");
		}
		// 需要修改密码时进行加密
		if (StringUtils.isNotBlank(form.getPassword())) {
			entity.setPassword(this.passwordEncoder.encode(form.getPassword()));
		}
	}

	/**
	 * 复制属性时忽略的字段
	 *
	 * @return 忽略字段
	 */
	@Override
	public String[] ignoredProperties() {
		return new String[]{ "password" };
	}

	/**
	 * 获取用户角色
	 * @param userId 用户ID
	 * @return 结果对象
	 */
	@ApiOperation("获取用户角色")
	@GetMapping("/roles")
	public ResultVO getUserRoles(@RequestParam Long userId) {
		Optional<SysUser> sysUserOptional = this.sysUserService.get(userId);
		if (sysUserOptional.isEmpty()) {
			return ResultUtils.failure("用户不存在");
		}
		Set<SysRole> userRoles = sysUserOptional.get().getUserRoles();
		return ResultUtils.success("成功", userRoles.stream().map(SysRole::getRoleId).collect(Collectors.toList()));
	}

	/**
	 * 分配角色
	 * @param userId 用户ID
	 * @param roleIds 角色ID字符串（用英文逗号分隔）
	 * @return 结果对象
	 */
	@ApiOperation("分配角色")
	@PutMapping("/allocate")
	public ResultVO allocate(@RequestParam Long userId, @RequestParam String roleIds) {
		if (Objects.equals(userId, SecurityConstants.SUPER_ADMIN_USER_ID)) {
			return ResultUtils.failure("不能为超级管理员用户分配角色");
		}
		Optional<SysUser> sysUserOptional = this.sysUserService.get(userId);
		if (sysUserOptional.isEmpty()) {
			return ResultUtils.failure("用户不存在");
		}
		SysUser sysUser = sysUserOptional.get();
		Set<SysRole> userRoles = sysUser.getUserRoles();
		// 获取选中的角色
		List<SysRole> allRoles = this.sysRoleService.getList(Arrays.stream(StringUtils.split(roleIds, ",")).map(Long::parseLong).collect(Collectors.toList()));

		// 找出需要删除的
		Set<SysRole> deleteRoles = userRoles.stream()
				.filter(sysRole -> !allRoles.contains(sysRole))
				.collect(Collectors.toSet());
		userRoles.removeAll(deleteRoles);
		userRoles.addAll(allRoles);
		this.sysUserService.modify(sysUser);
		return ResultUtils.success("角色分配成功");
	}

	/**
	 * 删除之前做的检测操作
	 *
	 * @param entity 实体对象
	 */
	@Override
	public void beforeDelete(SysUser entity) {
		if (Objects.equals(entity.getUserId(), SecurityConstants.SUPER_ADMIN_USER_ID)) {
			// 不能删除超级管理员用户
			throw new UpdateDeniedException("不能删除超级管理员用户");
		}
	}

}
